import api from "@/api"
import dayjs from "dayjs"

// 简单节流：限制函数触发频率
export function throttle(func: Function, wait: number, self: any) {
  let time = Date.now()
  return function (...args: any) {
    let current = Date.now()
    if (current - time > wait) {
      func.apply(self || null, args)
      time = current
    }
  }
}

/**
 *
 *
 * @export 提交数据时去除字符串两边的空格
 * @param {*} params
 * @returns
 */
export function stringTrim(params: any) {
  if (Array.isArray(params)) {
    for (let i = 0; i < params.length; i++) {
      params[i] = stringTrim(params[i])
    }
  } else if (typeof params == "object") {
    for (let key in params) {
      params[key] = stringTrim(params[key])
    }
  } else if (typeof params == "string") {
    params = params.trim()
  }
  return params
}

const toString = Object.prototype.toString
export function isPlainObject(val: any) {
  return toString.call(val) == "[object Object]"
}

export function formatTime(time: string, format = "YYYY-MM-DD HH:mm:ss") {
  return time ? dayjs(time).format(format) : "--"
}

// 金额格式化函数 100000 => 100,000
export function formatPrice(number: number) {
  if (isNaN(Number(number))) return "--"
  let numberStr = String(number)
  let temp = ""
  let formatStr = ""
  while (numberStr.length > 3) {
    temp = "," + numberStr.slice(-3)
    numberStr = numberStr.slice(0, numberStr.length - 3)
    formatStr = temp + formatStr
  }
  formatStr = numberStr + formatStr
  return formatStr
}

export function toFixed(val: number) {
  return (val / 100).toFixed(2)
}

// 展开省市区树形结构
export function expandArr(arr: any[], arr1: any[]) {
  arr.forEach((el) => {
    if (el.children) {
      expandArr(el.children, arr1)
    } else {
      arr1.push(el)
    }
  })
  return arr1
}

// 格式化显示
export function format(val: string | number) {
  if (val || val === 0) {
    return val
  }
  return "--"
}
export const clickSec = 5000
// 手机号码正则
export const phoneReg = /^1[3456789]\d{9}$/

// 设备编码正则
export const electricCodeReg = /^(\d{12}|\d{14})$/
export const mcbCodeReg = /^[0-9A-z]{18}$/

export const mcbCode = /^[0-9A-z]{18}$/

// 账号正则
export const accountReg = /^[0-9A-z]{4,20}$/

// 整数正则（账号不能为纯数字）
export const intergerReg = /^(-?[0-9]+|[0-9]*)$/

// 包含中文的正则
export const noChineseReg = /^[^\u4e00-\u9fa5]{0,}$/
// 包含非法字符串正则
export const noIllegalCharacters =
  /^[^~!@#$%^&*()_\-+=<>?:"{}|,.\/;'\\[\]·~！@#￥%……&*（）——\-+={}|《》？：“”【】、；‘'，。、]+$/

// 邮箱正则
export const emailReg = /^[a-z0-9]+([._\\-]*[a-z0-9])*@([a-z0-9]+[-a-z0-9]*[a-z0-9]+.){1,63}[a-z0-9]+$/

// 密码正则（字母+数字）
export const pwdReg = /(?=.*[A-Za-z])(?=.*[\d])/

export const pwdwdReg = /^(?=.*\d)(?=.*[a-z])(?=.*[A-Z])(?=.*[!@#$%^&*])(?!.*\s).{6,}$/

// 整数或小数正则
export const numberReg = /^[0-9]+(\.{0,1}[0-9]+)?$/

// 身份证号码正则
export const identifyReg =
  /(^[1-9]\d{5}(18|19|([23]\d))\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\d{3}[0-9Xx]$)|(^[1-9]\d{5}\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\d{3}$)/

/* 一系列判断数据结构的函数, 用来提示输入 */

// 是否
export const isInterger = (val: string) => {
  if (!intergerReg.test(val)) {
    return "请输入整数"
  }
  return ""
}
export const isInRange = (min: number, max: number, val: number) => {
  if (val < min || val > max) {
    return "请输入取值范围内的值"
  }
  return ""
}
export const isNumber = (val: number) => {
  if (isNaN(val)) {
    return "请输入数值"
  }
  return ""
}
export const isInTextRange = (length: number, val: string) => {
  if (val.length > length) {
    return `请输入长度小于${length}的字符串`
  }
  return ""
}
/*  end  */

// 产生图片访问地址
const env = process.env.NODE_ENV
const proxy = env === "development" ? "api/" : "api/"
// 图片上传路径.绝对路径写法
export const uploadBaseUrl = "/" + proxy

// 根据id创建图片链接
export function createImgUrl(id: string) {
  const host = document.domain
  let fileLink: string = window.location.origin || ""
  if (host == "localhost") {
    fileLink = process.env.VUE_APP_FILE_SERVER || ""
  }
  const readPath = "file/read"
  const url = fileLink + "/" + proxy + readPath + "?id=" + id
  return url
}

/**
 *
 *
 * @export 深拷贝
 * @param {*} raw
 * @returns
 */
export function deepCopy(raw: any) {
  if (raw === null || typeof raw !== "object") {
    return raw
  }
  let obj: any = Array.isArray(raw) ? [] : {}
  Object.keys(raw).forEach((key) => {
    obj[key] = deepCopy(raw[key])
  })
  return obj
}

/**
 * @description: 找出第一个可访问菜单路径
 * @param {menus} - this.$store.state.menus
 * @return: 第一个可访问的菜单路径
 */
export function getFirstRoute(menus: any[]) {
  let path
  let stop = false
  dfs(menus)
  return path
  // 深度遍历
  function dfs(menus: any[]) {
    if (stop || !menus) return
    for (let i = 0; i < menus.length; i++) {
      if (
        menus[i].url.toLowerCase() !== "#" &&
        menus[i].isOperation == "N" &&
        menus[i].isPermission == "Y" &&
        menus[i].isMainMenu == "Y" &&
        menus[i].state == "ENABLE"
      ) {
        if (stop) return
        path = menus[i].url
        stop = true
        return
      } else {
        dfs(menus[i].childList)
      }
    }
  }
}

/**
 *
 *
 * @export html5获取当前位置经纬度
 * @returns { Promise }Promise
 */
export function locationCurrentPosition() {
  return new Promise((resolve, reject) => {
    if (window.navigator.geolocation) {
      navigator.geolocation.getCurrentPosition(
        function (position) {
          let pos = {
            lat: position.coords.latitude,
            lng: position.coords.longitude
          }
          resolve(pos)
        },
        function () {
          reject()
        }
      )
    } else {
      reject()
    }
  })
}

/**
 *
 *
 * @export
 * @param { String } str
 * @param { Number } limit
 * @returns { String }
 */
export function limitWord(str: string, limit: number) {
  return str.length > limit ? str.slice(0, limit) + "..." : str
}

const ua = window.navigator.userAgent
//
export const isIE =
  /msie\s|trident\//i.test(ua) &&
  !!(
    "uniqueID" in document ||
    "documentMode" in document ||
    "ActiveXObject" in window ||
    "MSInputMethodContext" in window
  )

// 新版edge中为 Edg/
export const isOldEdge = /edge\//i.test(ua)

/**
 * @description 金额转换为中文大写形式
 * @export
 * @param {string} currencyDigits
 * @returns
 */
export function convertCurrency(currencyDigits: string) {
  // Constants:
  const MAXIMUM_NUMBER = 99999999999.99
  // Predefine the radix characters and currency symbols for output:
  const CN_ZERO = "零"
  const CN_ONE = "壹"
  const CN_TWO = "贰"
  const CN_THREE = "叁"
  const CN_FOUR = "肆"
  const CN_FIVE = "伍"
  const CN_SIX = "陆"
  const CN_SEVEN = "柒"
  const CN_EIGHT = "捌"
  const CN_NINE = "玖"
  const CN_TEN = "拾"
  const CN_HUNDRED = "佰"
  const CN_THOUSAND = "仟"
  const CN_TEN_THOUSAND = "万"
  const CN_HUNDRED_MILLION = "亿"
  const CN_SYMBOL = "" //'人民币'
  const CN_DOLLAR = "元"
  const CN_TEN_CENT = "角"
  const CN_CENT = "分"
  const CN_INTEGER = "整"
  const CN_NAGATIVE = "负"

  // Variables:
  let integral // Represent integral part of digit number.
  let decimal // Represent decimal part of digit number.
  let outputCharacters = "" // The output result.
  let parts
  let digits, radices, bigRadices, decimals
  let zeroCount
  let i, p, d
  let quotient, modulus

  // Validate input string:
  currencyDigits = currencyDigits.toString()
  if (currencyDigits == "") {
    return "--"
  }
  if (currencyDigits.match(/[^,.-\d]/) != null) {
    return "--"
  }

  if (currencyDigits.match(/^(-*(\d{1,3}(,\d{3})*(.((\d{3},)*\d{1,3}))?)|(\d+(.\d+)?))$/) == null) {
    return "--"
  }

  // Normalize the format of input digits:
  currencyDigits = currencyDigits.replace(/,/g, "") // Remove comma delimiters.
  currencyDigits = currencyDigits.replace(/^0+/, "") // Trim zeros at the beginning.
  // Assert the number is not greater than the maximum number.
  if (Number(currencyDigits) > MAXIMUM_NUMBER) {
    return "--"
  }

  // 检查是不是负数
  if (currencyDigits.indexOf("-") === 0) {
    currencyDigits = currencyDigits.replace("-", "")
    outputCharacters = CN_NAGATIVE
  }

  // Process the coversion from currency digits to characters:
  // Separate integral and decimal parts before processing coversion:
  parts = currencyDigits.split(".")
  if (parts.length > 1) {
    integral = parts[0]
    decimal = parts[1]
    // Cut down redundant decimal digits that are after the second.
    decimal = decimal.substr(0, 2)
  } else {
    integral = parts[0]
    decimal = ""
  }
  // Prepare the characters corresponding to the digits:
  digits = new Array(CN_ZERO, CN_ONE, CN_TWO, CN_THREE, CN_FOUR, CN_FIVE, CN_SIX, CN_SEVEN, CN_EIGHT, CN_NINE)
  radices = new Array("", CN_TEN, CN_HUNDRED, CN_THOUSAND)
  bigRadices = new Array("", CN_TEN_THOUSAND, CN_HUNDRED_MILLION)
  decimals = new Array(CN_TEN_CENT, CN_CENT)
  // Start processing:
  // Process integral part if it is larger than 0:
  if (Number(integral) > 0) {
    zeroCount = 0
    for (i = 0; i < integral.length; i++) {
      p = integral.length - i - 1
      d = integral.substr(i, 1)
      quotient = p / 4
      modulus = p % 4
      if (d == "0") {
        zeroCount++
      } else {
        if (zeroCount > 0) {
          outputCharacters += digits[0]
        }
        zeroCount = 0
        outputCharacters += digits[Number(d)] + radices[modulus]
      }
      if (modulus == 0 && zeroCount < 4) {
        outputCharacters += bigRadices[quotient]
        zeroCount = 0
      }
    }
    outputCharacters += CN_DOLLAR
  }
  // Process decimal part if there is:
  if (decimal != "") {
    for (i = 0; i < decimal.length; i++) {
      d = decimal.substr(i, 1)
      if (d != "0") {
        outputCharacters += digits[Number(d)] + decimals[i]
      }
    }
  }
  // Confirm and return the final output string:
  if (outputCharacters == "") {
    outputCharacters = CN_ZERO + CN_DOLLAR
  }
  if (decimal == "") {
    outputCharacters += CN_INTEGER
  }
  outputCharacters = CN_SYMBOL + outputCharacters
  return outputCharacters
}

// 首页数值转成字符串特殊处理
export const numberToString = (num: number) => {
  let str = Math.trunc(num).toString()
  let arr = str.split("").reverse()
  let copyArr = JSON.parse(JSON.stringify(arr))
  let index = 0 // 第几次加逗号
  arr.map((item, i) => {
    // 每三位加个逗号
    if ((i + 1) % 3 === 0) {
      copyArr.splice(i + index + 1, 0, ",")
      index++
    }
  })

  if (copyArr[copyArr.length - 1] === ",") {
    copyArr.splice(copyArr.length - 1, 1)
  }
  return parseFloat(copyArr.reverse().join("")).toFixed(2)
}

// 首页数值取小数部分
export const getDecimals = (num: number) => {
  let str = num.toString()
  if (str.indexOf(".") > -1) {
    return "." + str.split(".")[1]
  } else {
    return null
  }
}

// 时间（分钟） => HH:mm
export const formatMinuteToStr = (minute: number) => {
  const h = (minute / 60 + "").padStart(2, "0")
  const m = (Math.floor(minute % 60) + "").padStart(2, "0")
  return `${h}:${m}`
}

// 生成随机长度的 字母+数字 密码
export function getRandomPwd(len: number) {
  len = len || 32
  const $chars = "ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz2345678" // 默认去掉了容易混淆的字符oOLl,9gq,Vv,Uu,I1
  const maxPos = $chars.length
  let pwd = ""
  for (let i = 0; i < len; i++) {
    pwd += $chars.charAt(Math.floor(Math.random() * maxPos))
  }
  return pwd
}

// 非空判断
export function isNotNull(val: any) {
  return val !== null && val !== undefined && val !== ""
}

/**
 *
 * @param {*} val 要转换的数据
 * @param {*} fixed 保留的小数位数。默认保留2位小数
 * @param {*} deValue 传入的数据为无效值，返回的默认值。默认为'--'
 * @returns 返回转换后的字符串，默认情况下 传入1000000 返回 1,000,000.00
 */
export function formatNumWithComma(val: any, fixed = 2, deValue = "--") {
  if (typeof val !== "number" && typeof parseFloat(val) !== "number") {
    return deValue
  }
  if (val === 0) {
    return val.toFixed(fixed)
  }
  val = parseFloat(val).toFixed(fixed).toString()
  const integer = val.split(".")[0]
  const decimal = val.split(".")[1] || ""
  let temp = ""
  let index = 0
  if (integer.length <= 3) {
    return `${integer}${decimal ? "." + decimal : ""}`
  }
  while (index + integer.length > 3) {
    index = index - 3
    temp = "," + integer.substr(index, 3) + temp
  }
  temp = integer.slice(0, index) + temp
  return `${temp}${decimal ? "." + decimal : ""}`
}

export function renderCode(type = "device") {
  var date = new Date() // 获取时间
  var year = date.getFullYear() // 获取年
  var month = date.getMonth() + 1 // 获取月
  var strDate = date.getDate() // 获取日
  return type + date.getTime() + "" + Math.floor(Math.random() * Math.random() * 1000000)
}
